package sqlite_conf_table

import (
	"database/sql"
	"encoding/json"
	"github.com/sirupsen/logrus"
	"go-iot-gateway/internal/conf_table/define"
	"strconv"
	"strings"
)

var tbDeviceInfoColumns = []string{
	"id",
	"chl_id",
	"dev_name",
	"dev_desc",
	"dev_comm_addr",
	"dev_pub_addr",
	"dev_valid",
	"dev_manu",
	"dev_model",
	"reserve0",
	"reserve1",
	"dev_id",
}

var (
	//deviceConfInfoEntitySptr unsafe.Pointer
	_deviceConfInfoArr map[string]*conf_table_define.DeviceInfo //key dev_id
)

func DeviceConfInfoList() map[string]*conf_table_define.DeviceInfo {
	return _deviceConfInfoArr
	//return *(*[]conf_table.DeviceInfo)(atomic.LoadPointer(&deviceConfInfoEntitySptr))
}

func selectDeviceConfInfo(db *sql.DB) error {
	//查询t
	fields := strings.Join(tbDeviceInfoColumns, ",")
	selectSql := "select " + fields + " from tb_device_info order by id"
	rows, err := db.Query(selectSql)
	if err != nil {
		return err
	}
	defer func() {
		err := rows.Close()
		if err != nil {
			logrus.Warn("行关闭失败")
			return
		}
	}()

	_deviceConfInfoArr, err = convertDeviceConfInfo(rows)
	if err != nil {
		return err
	}
	//atomic.StorePointer(&deviceConfInfoEntitySptr, unsafe.Pointer(&info))
	return nil
}

type tbDeviceConfInfoEntity struct {
	id            *int
	chl_id        *string
	dev_name      *string
	dev_desc      *string
	dev_comm_addr *string
	dev_pub_addr  *string
	dev_valid     *int
	dev_manu      *string
	dev_model     *string
	reserve0      *string
	reserve1      *string
	dev_id        *string
}

func convertDeviceConfInfo(rows *sql.Rows) (map[string]*conf_table_define.DeviceInfo, error) {
	err := rows.Err()
	if err != nil {
		return nil, err
	}

	channelInfos := ChannelInfoList()

	resultMap := make(map[string]*conf_table_define.DeviceInfo)
	for rows.Next() {
		entity := tbDeviceConfInfoEntity{}
		err := rows.Scan(
			&entity.id,
			&entity.chl_id,
			&entity.dev_name,
			&entity.dev_desc,
			&entity.dev_comm_addr,
			&entity.dev_pub_addr,
			&entity.dev_valid,
			&entity.dev_manu,
			&entity.dev_model,
			&entity.reserve0,
			&entity.reserve1,
			&entity.dev_id)

		if err != nil {
			return nil, err
		}
		//todo 默认值
		item := &conf_table_define.DeviceInfo{}

		if entity.id != nil {
			item.Id = *entity.id
		}
		//if entity.chl_id != nil {
		//	item.Chl_id = *entity.chl_id
		//}
		if entity.dev_name != nil {
			item.Dev_name = strings.TrimSpace(*entity.dev_name)
		}
		if entity.dev_desc != nil {
			item.Dev_desc = strings.TrimSpace(*entity.dev_desc)
		}
		if entity.dev_comm_addr != nil {
			item.Dev_comm_addr = strings.TrimSpace(*entity.dev_comm_addr)
			item.Dev_comm_addr_int, _ = strconv.ParseInt(item.Dev_comm_addr, 10, 64)
		}
		if entity.dev_pub_addr != nil {
			item.Dev_pub_addr = strings.TrimSpace(*entity.dev_pub_addr)
			item.Dev_pub_addr_int, _ = strconv.ParseInt(item.Dev_pub_addr, 10, 64)
		}
		if entity.dev_valid != nil {
			item.Dev_valid = *entity.dev_valid
		}
		if entity.dev_manu != nil {
			item.Dev_manu = *entity.dev_manu
		}
		if entity.dev_model != nil {
			item.Dev_model = *entity.dev_model
		}
		if entity.reserve0 != nil {
			extraInfo := &conf_table_define.DeviceExtraInfo{}
			err := json.Unmarshal([]byte(*entity.reserve0), extraInfo)
			if err != nil {
				logrus.Warn("设备额外信息获取失败", err)
			}
			item.ExtraInfo = *extraInfo
		}
		if entity.reserve1 != nil {
			item.Reserve1 = *entity.reserve1
		}
		if entity.dev_id != nil {
			item.Dev_id = strings.TrimSpace(*entity.dev_id)
		}

		item.ChannelInfo = channelInfos[*entity.chl_id]
		resultMap[item.Dev_id] = item
	}

	return resultMap, nil
}
